#include "TerrainSegment.h"
#include "Terrain.h"
#include "RandomUtil.h"

using namespace std;

TerrainSegment::TerrainSegment(Vect3D aV, Vect3D bV, Vect3D cV, int s) : size(s), drawMe(true)
{
	noise = PerlinNoise(1.10,2.0,8);

	float xPos = aV.x + bV.x + cV.x;
	float yPos = Terrain::getHeight(aV.x,aV.z) + Terrain::getHeight(bV.x,bV.z) + Terrain::getHeight(cV.x,cV.z);
	float zPos = aV.z + bV.z + cV.z;

	a.x = aV.x;
	a.y = Terrain::getHeight(aV.x,aV.z);
	a.z = aV.z;

	b.x = bV.x;
	b.y = Terrain::getHeight(bV.x,bV.z);
	b.z = bV.z;

	c.x = cV.x;
	c.y = Terrain::getHeight(cV.x,cV.z);
	c.z = cV.z;

	xPos /= 3;
	yPos /= 3;
	zPos /= 3;

	loc = Location(xPos,yPos,zPos);

	//SceneNode *transNode = new TranslateNode(loc);
	GeomNode * triNode = BuildTri(a,b,c);
	triNode->SetMaterial((float)RandomUtil::random(0,5),25.0f,(float)RandomUtil::random(0,5));
	//transNode->AddChild(triNode);
	root.AddChild(triNode);
}

TerrainSegment::~TerrainSegment(void)
{
	cout << "Deleting TerrainSegment";
}

SceneRoot* TerrainSegment::getDrawables(void)
{
	return &root;
}

void TerrainSegment::update(void)
{
	return;
}

int TerrainSegment::getSize(void)
{
	return size;
}

Location TerrainSegment::getLocation(void)
{
	return loc;
}

bool TerrainSegment::draw(void)
{
	return drawMe;
}

bool TerrainSegment::deleteMe(void) {
	return deleteThis;
}

void TerrainSegment::setDraw(bool d)
{
	drawMe = d;

	return;
}

bool TerrainSegment::canSplit(void)
{
	return drawMe;
}

std::list<WorldObject *> TerrainSegment::split(void)
{
	float midX;
	float midZ;
	bool ignore = false;
	int mult=500;
	std::list<WorldObject *> segments;

	midX = (a.x+b.x+c.x)/3;
	midZ = (a.z+b.z+c.z)/3;
	Vect3D midVect(midX, Terrain::getHeight(midX,midZ), midZ);

	Vect3D newA, newB, newC;
	float lenAB, lenAC, lenBC;
	float tol = 0.01f;

	if ((a.x - b.x) < tol) {
		lenAB = max(a.z,b.z) - min (a.z, b.z);
	}
	else if ((a.z - b.z) < tol) {
		lenAB = max(a.x,b.x) - min (a.x, b.x);
	}
	else {
		newA = a;
		newB = c;
		newC = b;
		ignore = true;
	}

	if ((a.x - c.x) < tol) {
		lenAC = max(a.z,c.z) - min (a.z, c.z);
	}
	else if ((a.z - c.z) < tol) {
		lenAC = max(a.x,c.x) - min (a.x, c.x);
	}
	else {
		newA = a;
		newB = b;
		newC = c;
		ignore = true;
	}


	if ((b.x - c.x) < tol) {
		lenBC = max(b.z,c.z) - min (b.z, c.z);
	}
	else if ((a.z - c.z) < tol) {
		lenBC = max(b.x,c.x) - min (b.x, c.x);
	}

	if (!ignore) {
		if (lenAB == lenAC) {
			newA = b;
			newB = a;
			newC = c;
		}
	}
	else if (!ignore) {
		if (lenAB == lenBC) {
			newA = a;
			newB = b;
			newC = c;
		}
	}
	else if (!ignore) {
		if (lenAC == lenBC) {
			newA = a;
			newB = c;
			newC = b;
		}
	}

	float ohA = newA.y;
	float ohB = newB.y;
	float ohC = newC.y;

	//newA.y = Terrain::getHeight(newA.x,newA.z);
	//newB.y = Terrain::getHeight(newB.x,newB.z);
	//newC.y = Terrain::getHeight(newC.x,newC.z);

	Vect3D midPoint((newA.x+newC.x) / 2,0,(newA.z+newC.z) / 2);
	Vect3D midPoint2((newA.x+newC.x) / 2,(newA.y+newC.y) / 2,(newA.z+newC.z) / 2);
	midPoint.y = Terrain::getHeight(midPoint.x,midPoint.z);
	

	segments.push_back(new TerrainSegment(newA,newB,midPoint, size/10));
	segments.push_back(new TerrainSegment(midPoint,newB,newC, size/10));

	segments.push_back(new TerrainSegment(newA,midPoint,midPoint2, size/10));
	segments.push_back(new TerrainSegment(midPoint,midPoint2,newC, size/10));
	//segments.push_back(new TerrainSegment(a, midVect, b, size/10));
	//segments.push_back(new TerrainSegment(b, midVect, c, size/10));
	//segments.push_back(new TerrainSegment(c, midVect, a, size));
	
/*
	segments.push_back(new TerrainSegment(a, Vect3D((a.x-b.x)/2+b.x, (a.y-b.y)/2+b.y, (a.z-b.z)/2+b.z), midVect, size));
	segments.push_back(new TerrainSegment(Vect3D((a.x-b.x)/2+b.x, (a.y-b.y)/2+b.y, (a.z-b.z)/2+b.z), b, midVect, size));
	segments.push_back(new TerrainSegment(b, Vect3D((b.x-c.x)/2+c.x, (b.y-c.y)/2+c.y, (b.z-c.z)/2+c.z), midVect, size));
	segments.push_back(new TerrainSegment(Vect3D((b.x-c.x)/2+c.x, (b.y-c.y)/2+c.y, (b.z-c.z)/2+c.z), c, midVect, size));
	segments.push_back(new TerrainSegment(c, Vect3D((c.x-a.x)/2+a.x, (c.y-a.y)/2+a.y, (c.z-a.z)/2+a.z), midVect, size));
	segments.push_back(new TerrainSegment(a, Vect3D((c.x-a.x)/2+a.x, (c.y-a.y)/2+a.y, (c.z-a.z)/2+a.z), midVect, size));
*/

	return segments;
}

Vect3D TerrainSegment::getA()
{
	return a;
}

Vect3D TerrainSegment::getB()
{
	return b;
}

Vect3D TerrainSegment::getC()
{
	return c;
}

void TerrainSegment::setDelete(bool d) {
	deleteThis = d;
}